package com.base.cn.platform.os.common.mybatis.sharding;

import com.base.cn.platform.os.common.utils.ObjectUtils;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import java.util.*;

/**
 * 分表规则
 * @author s.li
 * @date 2019/04/10
 */
@ConfigurationProperties(prefix = "split.config.rule")
@Component
@Data
@Slf4j
public class ShardingTableRule {
    /**算法Map集合*/
    private Map<String,ShardingTableAlgorithm> shardingTableAlgorithmMap = new HashMap<>();
    /**分表的列的Map*/
    private Map<String,String> tables;
    //算法全类名属性的后缀
    private static final String ALGORITHM_CLASS_SUFFIX=".algorithm.class";
    //切片列名属性的后缀
    private static final String SHARDING_COLUMNS_SUFFIX=".columns";

    public Set<String> getTableNameSet(){
        if(this.tables != null){
            Set<String> tableNameSet = new HashSet<>();
            tables.forEach((k,v)->{
                String tableName = k.split("\\.")[0];
                tableNameSet.add(tableName);
            });
            return tableNameSet;
        }
        return null;
    }

    /**
     * 获取分片列名，以表名为KEY，分片列为Set集合
     * @return
     */
    public Map<String,Set<String>> getShardingColumns(){
        if(this.tables != null){
            Map<String,Set<String>> columnSetMap =new HashMap<>();
            tables.forEach((k,v)->{
                Set<String> columnSet = new HashSet<>();
                if(k.contains(SHARDING_COLUMNS_SUFFIX) && v!=null && !v.trim().equals("")){
                    String[] arr = v.split(",");
                    String tableName = k.split("\\.")[0];
                    Arrays.stream(arr).forEach(columnName->{
                        columnSet.add(columnName.toLowerCase());
                    });
                    columnSetMap.put(tableName.toLowerCase(),columnSet);
                }
            });
            if(ObjectUtils.isNotEmpty(columnSetMap)){
                return columnSetMap;
            }
        }
        return null;
    }

    /**
     * 初始化
     */
    public void init(){
        if(this.tables !=null){
            this.tables.forEach((k,v)->{
                if(k.contains(ALGORITHM_CLASS_SUFFIX)){
                    String key = k.split("\\.")[0].toLowerCase();//以表名为key（小写）
                    ShardingTableAlgorithm algorithm = shardingTableAlgorithmMap.get(key);
                    //算法对象未创建，则去创建
                    if(!ObjectUtils.isNotEmpty(algorithm)){
                        //类的全名做KEY，算法对象做Value
                        shardingTableAlgorithmMap.put(key,createShardingTableAlgorithm(v));
                    }
                }
            });
        }
    }

    /**
     * 创建算法对象
     * @param className 算法实现类的全类名
     * @return 算法对象
     */
    private ShardingTableAlgorithm createShardingTableAlgorithm(String className){
        try {
            Class algorithmClass = Class.forName(className);
            return (ShardingTableAlgorithm)algorithmClass.newInstance();
        } catch (Exception e) {
            log.error("createShardingTableAlgorithm(String className) "+className+" error",e);
        }
        return null;
    }
}
